package com.cloudfun.campusshare.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.cloudfun.campusshare.common.constant.*;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.common.model.dto.*;
import com.cloudfun.campusshare.common.model.vo.*;
import com.cloudfun.campusshare.common.response.BaseResultFactory;
import com.cloudfun.campusshare.common.response.PageResult;
import com.cloudfun.campusshare.common.security.AuthenticationHolder;
import com.cloudfun.campusshare.entity.*;
import com.cloudfun.campusshare.repo.*;
import com.cloudfun.campusshare.service.CreatorPersistenceService;
import com.cloudfun.campusshare.service.PromotionService;
import com.cloudfun.campusshare.service.UserCouponService;
import com.cloudfun.campusshare.service.UserRelService;
import com.cloudfun.campusshare.util.AmountUtil;
import com.cloudfun.campusshare.util.DateUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created by CodeGenerator on 2020/06/06
 */
@Slf4j
@Service
public class PromotionServiceImpl extends CreatorPersistenceService implements PromotionService {

    @Autowired
    private PromotionRepo promotionRepo;

    @Autowired
    private UserRelService userRelService;

    @Autowired
    private PromotionProductTypeRepo promotionProductTypeRepo;

    @Autowired
    private CouponPromotionRepo couponPromotionRepo;

    @Autowired
    private DiscountPromotionRepo discountPromotionRepo;

    @Autowired
    private RebatePromotionRepo rebatePromotionRepo;

    @Autowired
    private UserCouponService userCouponService;

    @Autowired
    private UserCouponRepo userCouponRepo;

    @Autowired
    private UserEntityRepo userEntityRepo;

    @Override
    protected Class<?> getEntityClass() {
        return PromotionEntity.class;
    }

    @Override
    @Transactional
    public <T extends PromotionDTO> void create(T createDTO) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startTime = createDTO.getStartTime();
        LocalDateTime endTime = createDTO.getEndTime();
        String promotionId;
        if (endTime.isBefore(startTime)) {
            throw new BusinessException(Code.ERROR, "请输入正确的时间");
        }
        if (startTime.isBefore(now)) {
            throw new BusinessException(Code.ERROR, "请输入正确的时间");
        }
        List<PromotionEntity> list = promotionRepo.findAllByTypeAndWashPointIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(createDTO.getType(),
                createDTO.getWashPointId(),startTime, endTime);
        if(StringUtils.isNotBlank(createDTO.getId()) && CollectionUtils.isNotEmpty(list)){
            list = list.stream().filter(a -> !createDTO.getId().equals(a.getId())).collect(Collectors.toList());
        }
        if(list.size() >= 1){
            throw new BusinessException(Code.ERROR, "本洗衣点在该时间段内，已有同类型活动，届时可能无法正常上线");
        }
        if(StringUtils.isNotBlank(createDTO.getId())){
            promotionId = createDTO.getId();
            PromotionModifyDTO promotionModifyDTO = new PromotionModifyDTO();
            BeanUtil.copyProperties(createDTO, promotionModifyDTO, CopyOptions.create().setIgnoreNullValue(true));
            modify(promotionModifyDTO);
        }else{
            PromotionEntity promotionEntity = new PromotionEntity();
            BeanUtil.copyProperties(createDTO, promotionEntity, "productTypes");
            UserEntity userMerchant = userRelService.getUserMerchant(AuthenticationHolder.getUserId());
            promotionEntity.setMerchantId(userMerchant.getId());
            promotionEntity.setStatus(PromotionStatus.NEW);
            boolean success = false;
            for (int i = 0; i < 10; i++) {
                try {
                    // 设置编码
                    this.fillPromotionNo(promotionEntity, createDTO.getType());
                    promotionRepo.save(promotionEntity);
                    success = true;
                    break;
                } catch (ConstraintViolationException e) {
                    log.error("创建营销活动异常: ", e);
                }
            }
            if (!success) {
                log.error("创建营销活动异常，尝试次数耗尽");
                throw new BusinessException(Code.ERROR, "创建异常，请稍后重试");
            }
            promotionId = promotionEntity.getId();
            // 设置具体的活动
            PromotionType promotionType = createDTO.getType();
            switch (promotionType) {
                case COUPON:
                    CouponPromotionEntity couponPromotionEntity = new CouponPromotionEntity();
                    BeanUtil.copyProperties(createDTO, couponPromotionEntity);
                    couponPromotionEntity.setPromotionId(promotionId);
                    couponPromotionEntity.setIssuedQuantity(NumberUtils.INTEGER_ZERO);
                    couponPromotionRepo.save(couponPromotionEntity);
                    createDTO.setProductTypes(null);
                    break;
                case DISCOUNT:
                    DiscountPromotionEntity discountPromotionEntity = new DiscountPromotionEntity();
                    BeanUtil.copyProperties(createDTO, discountPromotionEntity);
                    discountPromotionEntity.setPromotionId(promotionId);
                    discountPromotionRepo.save(discountPromotionEntity);
                    break;
                case REBATE:
                    RebatePromotionEntity rebatePromotionEntity = new RebatePromotionEntity();
                    BeanUtil.copyProperties(createDTO, rebatePromotionEntity);
                    rebatePromotionEntity.setPromotionId(promotionId);
                    rebatePromotionEntity.setThreshold(rebatePromotionEntity.getThreshold() * AmountUtil.DEFAULT_MULTIPLIER);
                    rebatePromotionEntity.setRebateAmount(rebatePromotionEntity.getRebateAmount() * AmountUtil.DEFAULT_MULTIPLIER);
                    rebatePromotionRepo.save(rebatePromotionEntity);
                    break;
            }
        }
        // 关联设备类型
        List<ProductType> productTypes = createDTO.getProductTypes();
        if (CollectionUtils.isNotEmpty(productTypes)) {
            String finalPromotionId = promotionId;
            List<PromotionProductType> productTypeList = productTypes.stream()
                    .map(productType -> {
                        PromotionProductType promotionProductType = new PromotionProductType();
                        promotionProductType.setProductType(productType);
                        promotionProductType.setPromotionId(finalPromotionId);
                        return promotionProductType;
                    }).collect(Collectors.toList());
            // 先删除
            promotionProductTypeRepo.deleteByPromotionId(promotionId);
            promotionProductTypeRepo.saveAll(productTypeList);
        }
    }

    /**
     * 填充编码
     *
     * @param promotionEntity
     * @param promotionType
     */
    private void fillPromotionNo(PromotionEntity promotionEntity, PromotionType promotionType) {
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        Long todayCount = promotionRepo.countAllByCreateTimeGreaterThanEqual(DateUtil.toEpochMilli(todayStart) + "");
        if (todayCount == null) {
            todayCount = NumberUtils.LONG_ONE;
        }
        // 生成编码
        String promotionNo = this.genPromotionNo(promotionType, todayCount + 1);
        promotionEntity.setPromotionNo(promotionNo);
    }

    /**
     * “HD”+8位时间（活动创建日期）+1位活动类型（1：代金券活动，2折扣活动，3：满减活动）+5位序号需（保证活动ID号唯一）
     *
     * @param type
     * @param count
     * @return
     */
    private String genPromotionNo(PromotionType type, Long count) {
        return "HD" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) +
                (type.ordinal() + 1) +
                StringUtils.leftPad(String.valueOf(count), 5, "0");
    }

    @Override
    public List<PromotionListVO> samePeriodPromotionList(SamePeriodPromotionSearchDTO promotionDTO) {
        Specification<PromotionEntity> spec = this.samePeriodSpec(promotionDTO);
        List<PromotionEntity> entities = promotionRepo.findAll(spec);
        return entities.stream().map(entity -> {
            PromotionListVO listVO = new PromotionListVO();
            BeanUtil.copyProperties(entity, listVO);
            return listVO;
        }).collect(Collectors.toList());
    }

    @Override
    public PageResult<PromotionListVO> search(PromotionSearchDTO searchDTO, Pageable pageable) {
        Specification<PromotionEntity> spec = this.spec(searchDTO);
        Page<PromotionEntity> page = promotionRepo.findAll(spec, pageable);
        List<PromotionListVO> content = page.getContent().stream()
                .map(entity -> {
                    PromotionListVO listVO = new PromotionListVO();
                    BeanUtil.copyProperties(entity, listVO);
                    List<PromotionProductType> productTypes = entity.getProductTypes();
                    if (CollectionUtils.isNotEmpty(productTypes)) {
                        listVO.setProductTypeList(productTypes.stream().map(PromotionProductType::getProductType).collect(Collectors.toList()));
                    }
                    WashPointEntity washPoint = entity.getWashPoint();
                    listVO.setWashPointName(washPoint.getName());
                    return listVO;
                }).collect(Collectors.toList());
        return new PageResult<>(page.getTotalElements(), content);
    }

    private Specification<PromotionEntity> spec(PromotionSearchDTO searchDTO) {
        return (root, query, cb) -> {
            query.distinct(true);
            Boolean viewAllData = AuthenticationHolder.getUserAuth().getViewAllData();
            List<Predicate> list = new ArrayList<>();
            if (AuthenticationHolder.isAdmin()) {
                if (!StringUtils.isBlank(searchDTO.getMerchantId())) {
                    list.add(cb.equal(root.get("merchantId"), searchDTO.getMerchantId()));
                }
            } else if (!AuthenticationHolder.isCustomer()) {
                if (viewAllData) {
                    String userId = AuthenticationHolder.getUserId();
                    UserEntity merchant = userRelService.getUserMerchant(userId);
                    list.add(cb.equal(root.get("merchantId"), merchant.getId()));
                } else {
                    Set<String> allSub = userRelService.getDescendantIds(AuthenticationHolder.getUserId());
                    allSub.add(AuthenticationHolder.getUserId());
                    list.add(root.get("creatorId").in(allSub));
                }
            }
            if (CollectionUtils.isNotEmpty(searchDTO.getTypes())) {
                list.add(root.get("type").in(searchDTO.getTypes()));
            }
            if (CollectionUtils.isNotEmpty(searchDTO.getProductTypes())) {
                Join<?, ?> productTypes = root.join("productTypes", JoinType.LEFT);
                list.add(productTypes.get("productType").in(searchDTO.getProductTypes()));
            }
            if (StringUtils.isNotBlank(searchDTO.getWashPointId())) {
                list.add(cb.equal(root.get("washPointId"), searchDTO.getWashPointId()));
            }
            if (null != searchDTO.getStatus()) {
                list.add(cb.equal(root.get("status"), searchDTO.getStatus()));
            }
            if (null != searchDTO.getStartTime()) {
                list.add(cb.greaterThanOrEqualTo(root.get("startTime"), searchDTO.getStartTime()));
            }
            if (null != searchDTO.getEndTime()) {
                list.add(cb.lessThanOrEqualTo(root.get("endTime"), searchDTO.getEndTime()));
            }
            if (StringUtils.isNotBlank(searchDTO.getKeyword())) {
                list.add(cb.like(root.get("name"), "%" + searchDTO.getKeyword() + "%"));
            }

            return cb.and(list.toArray(new Predicate[0]));
        };
    }

    private Specification<PromotionEntity> samePeriodSpec(SamePeriodPromotionSearchDTO searchDTO) {
        return (root, query, cb) -> {
            PromotionType promotionType = searchDTO.getPromotionType();
            LocalDateTime startTime = searchDTO.getStartTime();
            LocalDateTime endTime = searchDTO.getEndTime();
            List<Predicate> list = new ArrayList<>();
            list.add(cb.equal(root.get("washPointId"), searchDTO.getWashPointId()));
            list.add(cb.equal(root.get("type"), promotionType));
            if (null != searchDTO.getStatus()) {
                list.add(cb.equal(root.get("status"), searchDTO.getStatus()));
            }
            // 时间段
            List<Predicate> orConditions = new ArrayList<>();
            orConditions.add(cb.greaterThan(root.get("startTime"), endTime));
            orConditions.add(cb.lessThan(root.get("endTime"), startTime));
            list.add(cb.not(cb.or(orConditions.toArray(new Predicate[0]))));

            // 折扣和满减，有相同的设备类型才视为同一种类型的活动
            if (CollectionUtils.isNotEmpty(searchDTO.getProductTypes()) &&
                    (PromotionType.DISCOUNT.equals(promotionType) || PromotionType.REBATE.equals(promotionType))) {
                Join<?, ?> productTypeRelJoin = root.join("productTypes", JoinType.LEFT);
                list.add(productTypeRelJoin.get("productType").in(searchDTO.getProductTypes()));
            }

            Predicate[] predicates = new Predicate[list.size()];
            list.toArray(predicates);
            return cb.and(predicates);
        };
    }

    @Override
    public void modify(PromotionModifyDTO promotionDTO) {
        Optional<PromotionEntity> promotionEntityOptional = promotionRepo.findById(promotionDTO.getId());
        if (!promotionEntityOptional.isPresent()) {
            return;
        }
        PromotionEntity promotionEntity = promotionEntityOptional.get();
        promotionEntity.setStatus(PromotionStatus.NEW);
        BeanUtil.copyProperties(promotionDTO, promotionEntity, CopyOptions.create().setIgnoreNullValue(true));
        promotionRepo.save(promotionEntity);
    }

    @Override
    @Transactional
    public void delete(String id) {
        Optional<PromotionEntity> promotionEntityOptional = promotionRepo.findById(id);
        if (!promotionEntityOptional.isPresent()) {
            return;
        }
        PromotionEntity promotionEntity = promotionEntityOptional.get();
        if (promotionEntity.getStatus() == PromotionStatus.ONLINE) {
            throw new BusinessException(Code.ONLINE_PROMOTION_CAN_NOT_DELETED);
        }
        // 删除关联类型
        List<PromotionProductType> productTypes = promotionProductTypeRepo.findAllByPromotionId(id);
        promotionProductTypeRepo.deleteAll(productTypes);
        // 删除具体活动
        PromotionType type = promotionEntity.getType();
        switch (type) {
            case COUPON:
                couponPromotionRepo.delete(couponPromotionRepo.findByPromotionId(id));
                // 已领取的代金券活动Id设置为空
                userCouponRepo.updatePromotionId(id, null);
                break;
            case DISCOUNT:
                discountPromotionRepo.delete(discountPromotionRepo.findByPromotionId(id));
                break;
            case REBATE:
                rebatePromotionRepo.delete(rebatePromotionRepo.findByPromotionId(id));
                break;
        }
        // 删除活动
        promotionRepo.deleteById(id);
    }

    @Override
    @Transactional
    public void offline(List<String> ids) {
        List<PromotionEntity> entities = promotionRepo.findAllByIdIn(ids);
        this.offlineAll(entities);
    }

    @Override
    @Transactional
    public void offline(PromotionSearchDTO searchDTO) {
        Specification<PromotionEntity> spec = this.spec(searchDTO);
        List<PromotionEntity> entities = promotionRepo.findAll(spec);
        this.offlineAll(entities);
    }

    @Override
    @Transactional
    public void offlineAll() {
        PromotionSearchDTO searchDTO = new PromotionSearchDTO();
        searchDTO.setMerchantId("-1");
        Specification<PromotionEntity> spec = this.spec(searchDTO);
        List<PromotionEntity> entities = promotionRepo.findAll(spec);
        this.offlineAll(entities);
    }

    private void offlineAll(List<PromotionEntity> promotionEntities) {
        for (PromotionEntity entity : promotionEntities) {
            entity.setStatus(PromotionStatus.OFFLINE);
        }
        promotionRepo.saveAll(promotionEntities);
    }

    @Override
    public PromotionDetailVO detail(String id) {
        PromotionEntity entity = promotionRepo.findById(id).orElseThrow(() -> new BusinessException(Code.NODATA));
        PromotionType type = entity.getType();
        switch (type) {
            case COUPON:
                CouponPromotionDetailVO res = new CouponPromotionDetailVO();
                BeanUtil.copyProperties(entity, res);
                List<PromotionProductType> productTypes = entity.getProductTypes();
                if (CollectionUtils.isNotEmpty(productTypes)) {
                    res.setProductTypeList(entity.getProductTypes().stream().map(PromotionProductType::getProductType).collect(Collectors.toList()));
                }
                res.setWashPointName(entity.getWashPoint().getName());

                CouponPromotionEntity couponPromotionEntity = couponPromotionRepo.findByPromotionId(id);
                res.setCouponPromotionId(couponPromotionEntity.getId());
                res.setCouponId(couponPromotionEntity.getCouponId());
                res.setCouponName(couponPromotionEntity.getCoupon().getName());
                res.setAmount(AmountUtil.amountRoundStr(couponPromotionEntity.getCoupon().getAmount(), 2));
                res.setAccountDrawQuantity(couponPromotionEntity.getAccountDrawQuantity());
                res.setTotalQuantity(couponPromotionEntity.getTotalQuantity());
                if (AuthenticationHolder.isCustomer()) {
                    // 当前帐号已领取数量
                    Integer accountDrawQuantity = couponPromotionEntity.getAccountDrawQuantity();
                    long curUserDrewCount = userCouponRepo.countAllByPromotionIdAndUserId(id, AuthenticationHolder.getUserId());
                    Integer totalQuantity = couponPromotionEntity.getTotalQuantity();
                    long issuedQuantity = couponPromotionEntity.getIssuedQuantity();
                    long max = Math.max(Math.min(accountDrawQuantity - curUserDrewCount, totalQuantity - issuedQuantity), 0L);
                    res.setCurrUserAvailableQuantity(new Long(max).intValue());
                }
                return res;
            case DISCOUNT:
                DiscountPromotionDetailVO res1 = new DiscountPromotionDetailVO();
                BeanUtil.copyProperties(entity, res1);
                res1.setProductTypeList(entity.getProductTypes().stream().map(PromotionProductType::getProductType).collect(Collectors.toList()));
                res1.setWashPointName(entity.getWashPoint().getName());

                DiscountPromotionEntity discountPromotionEntity = discountPromotionRepo.findByPromotionId(id);
                res1.setDiscountPromotionId(discountPromotionEntity.getId());
                res1.setDiscount(discountPromotionEntity.getDiscount());
                return res1;
            case REBATE:
                RebatePromotionDetailVO res2 = new RebatePromotionDetailVO();
                BeanUtil.copyProperties(entity, res2);
                res2.setProductTypeList(entity.getProductTypes().stream().map(PromotionProductType::getProductType).collect(Collectors.toList()));
                res2.setWashPointName(entity.getWashPoint().getName());

                RebatePromotionEntity rebatePromotionEntity = rebatePromotionRepo.findByPromotionId(id);
                res2.setRebatePromotionId(rebatePromotionEntity.getId());
                res2.setThreshold(rebatePromotionEntity.getThreshold() / 100);
                res2.setRebateAmount(rebatePromotionEntity.getRebateAmount() / 100);
                return res2;
        }
        return null;
    }

    @Override
    public List<PromotionDetailVO> list(PromotionSearchDTO searchDTO) {
        Specification<PromotionEntity> spec = this.spec(searchDTO);
        List<PromotionEntity> promotionEntities = promotionRepo.findAll(spec);
        return promotionEntities.stream().map(entity -> this.detail(entity.getId())).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void drawCoupon(String id) {
        PromotionEntity promotionEntity = promotionRepo.findById(id).orElseThrow(() -> new BusinessException(Code.NODATA));
        LocalDateTime now = LocalDateTime.now();
        if (promotionEntity.getStatus() != PromotionStatus.ONLINE
                || promotionEntity.getStartTime().isAfter(now)
                || promotionEntity.getEndTime().isBefore(now)) {
            throw new BusinessException(Code.ERROR, "活动未开始或已下线");
        }
        CouponPromotionEntity couponPromotionEntity = couponPromotionRepo.findByPromotionId(id);
        if (null == couponPromotionEntity) {
            throw new BusinessException(Code.NODATA);
        }
        // 已领取数量大于等于总量时，不能领取
        if (couponPromotionEntity.getIssuedQuantity() >= couponPromotionEntity.getTotalQuantity()) {
            throw new BusinessException(Code.ERROR, "代金券已被领完");
        }
        // 账号已领取数量大于等于限制数量时，不能领取
        long drewCount = userCouponRepo.countAllByPromotionIdAndUserId(id, AuthenticationHolder.getUserId());
        if (drewCount >= couponPromotionEntity.getAccountDrawQuantity()) {
            throw new BusinessException(Code.ERROR, "代金券已领取");
        }

        CouponEntity coupon = couponPromotionEntity.getCoupon();
        // 创建
        String userId = AuthenticationHolder.getUserId();
        UserEntity userEntity = userEntityRepo.findById(userId).orElseThrow(() -> new BusinessException(Code.NODATA));
        UserCouponCreateDTO createDTO = new UserCouponCreateDTO();
        createDTO.setUserPhone(userEntity.getPhone());
        createDTO.setWashPointId(promotionEntity.getWashPointId());
        createDTO.setCouponType(CouponType.PROMOTION);
        createDTO.setAmount(AmountUtil.amountRoundStr(coupon.getAmount(), 2));
        int drawCount = 1;
        createDTO.setCount(drawCount);
        createDTO.setExpirationDate(now.plusDays(coupon.getValidDay()));
        createDTO.setCouponId(coupon.getId());
        createDTO.setPromotionId(id);
        createDTO.setIssuerId(promotionEntity.getCreatorId());
        createDTO.setIssuerName(promotionEntity.getCreatorName());
        UserEntity userMerchant = userRelService.getUserMerchant(promotionEntity.getMerchantId());
        createDTO.setMerchantId(userMerchant.getId());
        userCouponService.create(createDTO);
        // 更新
        int updateCount = couponPromotionRepo.updateIssuedQuantity(couponPromotionEntity.getId(), drawCount, AuthenticationHolder.getUserId());
        if (updateCount == NumberUtils.INTEGER_ZERO) {
            throw new BusinessException(Code.ERROR, "代金券已被领完");
        }
    }

    @Override
    public void autoChangeStatus() {
        Iterable<PromotionEntity> promotionEntities = promotionRepo.findAllByStatusInOrderByCreateTime(Lists.newArrayList(PromotionStatus.NEW, PromotionStatus.ONLINE));
        for (PromotionEntity entity : promotionEntities) {
            // 下线
            if (entity.getStatus() == PromotionStatus.ONLINE && entity.getEndTime().isBefore(LocalDateTime.now())) {
                entity.setStatus(PromotionStatus.OFFLINE);
                promotionRepo.save(entity);
                return;
            }
            // 上线
            if (entity.getStatus() == PromotionStatus.NEW && entity.getStartTime().isBefore(LocalDateTime.now())) {
                SamePeriodPromotionSearchDTO searchDTO = new SamePeriodPromotionSearchDTO();
                searchDTO.setPromotionType(entity.getType());
                searchDTO.setWashPointId(entity.getWashPointId());
                searchDTO.setStatus(PromotionStatus.ONLINE);
                List<PromotionProductType> productTypes = entity.getProductTypes();
                if (CollectionUtils.isNotEmpty(productTypes)) {
                    searchDTO.setProductTypes(productTypes.stream().map(PromotionProductType::getProductType).collect(Collectors.toList()));
                }
                searchDTO.setStartTime(entity.getStartTime());
                searchDTO.setEndTime(entity.getEndTime());
                List<PromotionListVO> voList = this.samePeriodPromotionList(searchDTO);
                if (voList.size() > 0) {
                    continue;
                }
                entity.setStatus(PromotionStatus.ONLINE);
                promotionRepo.save(entity);
            }
        }
    }
}